package com.ideaaedi.commonds.sort;


import java.util.Collection;
import java.util.List;

/**
 * 排序实现器
 *
 * @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
 * @since 1.0.0
 */
public interface SortSupporter<T extends Comparable<T>> {
    
    /**
     * 自动选择排序实现，并进行排序
     * <br/>
     * 注: 在当前逻辑下， 由于其是调用forkJoinMergeSort或collectionsSort， 所以也是稳定的.
     * <br/>
     * @param nonNullList
     *            非空集合(集合本身不为空， 集合里面的元素全都不为null)
     * @param asc
     *            true-与Comparable结果方向一致， false-与Comparable结果方向相反
     *            <ul>
     *                <li>当Comparable比较结果从小到大时, true-升序, false-降序</li>
     *                <li>当Comparable比较结果从大到小时, true-降序, false-升序</li>
     *            </ul>
     * @return 排完序后的集合
     */
    List<T> autoSort(Collection<T> nonNullList, boolean asc);
    
    /**
     * 【稳定排序】多线程归并排序
     * <br/>
     * @param nonNullList
     *            非空集合(集合本身不为空， 集合里面的元素全都不为null)
     * @param asc
     *            true-与Comparable结果方向一致， false-与Comparable结果方向相反
     *            <ul>
     *                <li>当Comparable比较结果从小到大时, true-升序, false-降序</li>
     *                <li>当Comparable比较结果从大到小时, true-降序, false-升序</li>
     *            </ul>
     * @return 排完序后的集合
     */
    List<T>  forkJoinMergeSort(Collection<T> nonNullList, boolean asc);
    
    /**
     * 【稳定排序】Collections.sort快速or归并排序
     * <br/>
     * @param nonNullList
     *            非空集合(集合本身不为空， 集合里面的元素全都不为null)
     * @param asc
     *            true-与Comparable结果方向一致， false-与Comparable结果方向相反
     *            <ul>
     *                <li>当Comparable比较结果从小到大时, true-升序, false-降序</li>
     *                <li>当Comparable比较结果从大到小时, true-降序, false-升序</li>
     *            </ul>
     * @return 排完序后的集合
     */
    List<T> collectionsSort(Collection<T> nonNullList, boolean asc);
    
    /**
     * 自定义排序
     * <br/>
     * @param nonNullList
     *            非空集合(集合本身不为空， 集合里面的元素全都不为null)
     * @param asc
     *            true-与Comparable结果方向一致， false-与Comparable结果方向相反
     *            <ul>
     *                <li>当Comparable比较结果从小到大时, true-升序, false-降序</li>
     *                <li>当Comparable比较结果从大到小时, true-降序, false-升序</li>
     *            </ul>
     * @return 排完序后的集合
     */
    default List<T> customizedSort(Collection<T> nonNullList, boolean asc) {
        throw new UnsupportedOperationException("temporarily does not support custom sorting");
    }
    
    /**
     * 排序
     *
     * @param nonNullList
     *         要被排序的数据集
     * @param sortStrategy
     *         排序策略
     * @param asc
     *            true-正向， false-反向
     *
     * @return  排序后的数据
     */
    default List<T> doSort(Collection<T> nonNullList, SortStrategy sortStrategy, boolean asc) {
        // 非空校验、不含null校验
        if (nonNullList == null || nonNullList.size() == 0) {
            throw new IllegalArgumentException("nonNullList cannot be empty.");
        }
        if (nonNullList.contains(null)) {
            throw new IllegalArgumentException("nonNullList cannot contain null.");
        }
        List<T> nonNullSortedList;
        switch (sortStrategy) {
            case AUTO:
                nonNullSortedList = autoSort(nonNullList, asc);
                break;
            case COLLECTIONS_SORT:
                nonNullSortedList = collectionsSort(nonNullList, asc);
                break;
            case FORK_JOIN_MERGE_SORT:
                nonNullSortedList = forkJoinMergeSort(nonNullList, asc);
                break;
            case CUSTOMIZED_SORT:
                nonNullSortedList = customizedSort(nonNullList, asc);
                break;
            default:
                throw new RuntimeException("un-support enums for [" + sortStrategy + "]");
        }
        return nonNullSortedList;
    }
}
